﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Xml.Linq;
using System.Runtime.Serialization;
using System.IO;
using System.IO.IsolatedStorage;
using System.Windows.Threading;
using System.Windows.Media.Imaging;
using System.Threading;

namespace loud_tweets
{
    public partial class MainPage : PhoneApplicationPage
    {
        List<string> tweetLoudList = new List<string>();
        string twitterUrl = "http://search.twitter.com/search.atom?q=";
        private const string speakUrl = "http://api.microsofttranslator.com/V2/Http.svc/Speak?appId={0}&text={1}&language={2}";
        private const string translateUrl = "http://api.microsofttranslator.com/V2/Http.svc/Translate?appId={0}&from=&to={1}&text={2}";
        string _appId = "";

        private DispatcherTimer timelineTimer;
        bool soundOn = true;
        List<TwitterObject> twitteList = new List<TwitterObject>();

        #region GUI

        public MainPage()
        {
            InitializeComponent();
        }

        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
        }

        private void txtTwitte_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                this.Focus();
            }
        }

        private void txtTwitte_LostFocus(object sender, RoutedEventArgs e)
        {
            //twitter();
            TwitterTimer();
        }

        private void imgTwitter_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            TwitterTimer();
        }

        private void lboTwitte_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            lboTwitte.SelectedIndex = -1;
        }

        private void imgSound_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Uri uri = new Uri("Images/sound_on.png", UriKind.Relative);
            ImageSource imgSoubd_on = new BitmapImage(uri);

            uri = new Uri("Images/sound_off.png", UriKind.Relative);
            ImageSource imgSoubd_off = new BitmapImage(uri);

            if (soundOn)
            {
                imgSound.Source = imgSoubd_off;
                soundOn = false;
                media.Stop();
            }
            else
            {
                imgSound.Source = imgSoubd_on;
                soundOn = true;
                tweetLoud();
            }


        }

        #endregion

        #region Content

        private void twitter()
        {
            try
            {
                if (txtTwitte.Text != "")
                {
                    lblLoading.Visibility = Visibility.Visible;
                    lboTwitte.Opacity = 0.3;

                    WebClient client = new WebClient();
                    client.DownloadStringAsync(new Uri(twitterUrl + txtTwitte.Text));
                    client.DownloadStringCompleted += ((s, e) =>
                    {
                        if (e.Error == null)
                        {
                            XDocument xml = XDocument.Parse(e.Result);
                            XNamespace atomNS = "http://www.w3.org/2005/Atom";

                            var tempList = (from entry in xml.Descendants(atomNS + "entry")
                                            select new TwitterObject()
                                            {
                                                ID = entry.Element(atomNS + "id").Value,
                                                Title = entry.Element(atomNS + "title").Value,
                                                Date = DateTime.Parse(entry.Element(atomNS + "published").Value),
                                                AuthorName = entry.Descendants(atomNS + "author").Elements(atomNS + "name").FirstOrDefault().Value,
                                                AuthorUri = entry.Descendants(atomNS + "author").Elements(atomNS + "uri").FirstOrDefault().Value,
                                                AuthorImage = (from imgElement in entry.Elements(atomNS + "link")
                                                               where imgElement.Attribute("rel") != null
                                                               && imgElement.Attribute("rel").Value.Contains("image")
                                                               && imgElement.Attribute("href") != null
                                                               select imgElement.Attribute("href").Value).FirstOrDefault()
                                            }).ToList();

                            twitteList = tempList.ToList();
                            lboTwitte.ItemsSource = twitteList;
                            lblLoading.Visibility = Visibility.Collapsed;
                            lboTwitte.Opacity = 1;

                            tweetLoud();
                        }
                    });
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void tweetLoud()
        {
            if (soundOn)
            {
                for (int i = 0; i < lboTwitte.Items.Count; i++)
                {
                    TwitterObject twitterObject = (TwitterObject)lboTwitte.Items[i];

                    if(!tweetLoudList.Contains(twitterObject.Title))
                    {
                        tweetLoudList.Add(twitterObject.Title);
                        translate(twitterObject.Title);
                        break;
                    }
                }
            }
        }

        private void translate(string text)
        {
            try
            {
                if (soundOn)
                {
                    text = removeHtml(text);
                    WebClient client = new WebClient();
                    client.OpenReadCompleted += new OpenReadCompletedEventHandler(translate_Completed);
                    client.OpenReadAsync(new Uri(string.Format(translateUrl, _appId, "en", HttpUtility.UrlEncode(text))));
                }
            }
            catch (Exception ex)
            {
                tweetLoud();
                MessageBox.Show(ex.ToString());
            }
        }

        void translate_Completed(object sender, OpenReadCompletedEventArgs e)
        {
            try{
                if (e.Error == null)
                {
                    DataContractSerializer data = new DataContractSerializer(typeof(string));
                    string response = data.ReadObject(e.Result) as string;
                    speek(response);
                }
                else
                {
                    tweetLoud();
                }
            }
            catch (Exception ex)
            {
                tweetLoud();
                MessageBox.Show(ex.ToString());
            }
        }

        private void speek(string text)
        {
            try
            {
                if (soundOn)
                {
                    WebClient client = new WebClient();
                    client.OpenReadCompleted += new OpenReadCompletedEventHandler(speek_Completed);
                    client.OpenReadAsync(new Uri(string.Format(speakUrl, _appId, text, "en")));
                }
            }
            catch (Exception ex)
            {
                tweetLoud();
                MessageBox.Show(ex.ToString());
            }
        }

        void speek_Completed(object sender, OpenReadCompletedEventArgs e)
        {
            try
            {
                if (e.Error == null)
                {
                    var sound = e.Result;

                    media.Source = null;
                    string filename = "twitter";
                    using (IsolatedStorageFile userStoreForApplication = IsolatedStorageFile.GetUserStoreForApplication())
                    {
                        bool fileExists = userStoreForApplication.FileExists(filename);

                        if (fileExists)
                        {
                            userStoreForApplication.DeleteFile(filename);
                        }

                        var isolatedStorageFileStream = userStoreForApplication.CreateFile(filename);

                        using (isolatedStorageFileStream)
                        {
                            SaveFile(e.Result, isolatedStorageFileStream);

                            if (e.Error == null)
                            {
                                media.SetSource(isolatedStorageFileStream);
                                media.Play();
                                media.MediaEnded += new RoutedEventHandler(media_MediaEnded);
                                //tweetLoud();
                            }
                        }
                    }
                }
                else
                {
                    tweetLoud();
                }
            }
            catch (Exception ex)
            {
                tweetLoud();
                MessageBox.Show(ex.ToString());
            }
        }

        void media_MediaEnded(object sender, RoutedEventArgs e)
        {
            try
            {
                tweetLoud();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        #endregion

        #region Tools

        private void TwitterTimer()
        {
            if (this.timelineTimer == null)
            {
                this.timelineTimer = new DispatcherTimer();
                this.timelineTimer.Tick += new EventHandler(TwitterTimer_Tick);
                this.timelineTimer.Interval = new TimeSpan(0, 1, 0);
                this.timelineTimer.Start();
            }

            this.TwitterTimer_Tick(this, EventArgs.Empty);
        }

        void TwitterTimer_Tick(object sender, EventArgs e)
        {
            twitter();
        }

        public static string removeHtml(string temp)
        {
            try
            {
                temp = temp.Replace("'", "`");
                temp = temp.Replace("â€“", "–");
                temp = temp.Replace("â€™", "`");
                temp = temp.Replace("â€™", "`");
                temp = temp.Replace("</a>", "");
                temp = temp.Replace("<strong>", "");
                temp = temp.Replace("</strong>", "");
                temp = temp.Replace("<p>", "");
                temp = temp.Replace("</p>", "");
                temp = temp.Replace("\r", "");
                temp = temp.Replace("\n", "");
                temp = temp.Replace("<b>", "");
                temp = temp.Replace("</b>", "");
                temp = temp.Replace("<em>", "");
                temp = temp.Replace("</em>", "");
                temp = temp.Replace("\t", "");
                temp = temp.Replace("<br>", Environment.NewLine);
                temp = temp.Replace("Ã¤", "ä");
                temp = temp.Replace("&nbsp;", " ");
                temp = temp.Replace("&quot;", "\"");
                temp = temp.Replace("&#160;", "");
                temp = temp.Replace("&#8230;", "");
                temp = temp.Replace("<ul>", Environment.NewLine);
                temp = temp.Replace("</ul>", Environment.NewLine);
                temp = temp.Replace("<li>", Environment.NewLine);
                temp = temp.Replace("</li>", Environment.NewLine);
                temp = temp.Replace("<br />", Environment.NewLine);

                if (temp.ToLower().Contains("http"))
                {
                    string url = temp.Substring(temp.ToLower().IndexOf("http"));
                    if (url.Contains(" "))
                    {
                        url = url.Substring(0, url.IndexOf(" "));
                        temp = temp.Replace(url, "");
                    }
                    else
                    {
                        temp = temp.Substring(0, temp.IndexOf("http"));
                    }
                }

                while (temp.Contains("<a"))
                {
                    string link = temp.Substring(temp.IndexOf("<a"));
                    link = link.Substring(0, link.IndexOf(">") + 1);

                    temp = temp.Replace(link, "");
                }

                while (temp.Contains("<img"))
                {
                    string link = temp.Substring(temp.IndexOf("<img"));
                    link = link.Substring(0, link.IndexOf(">") + 1);

                    temp = temp.Replace(link, "");
                }
            }
            catch { }

            return temp;
        }

        public static void SaveFile(Stream input, Stream output)
        {
            try
            {
                byte[] buffer = new byte[32768];
                while (true)
                {
                    int read = input.Read(buffer, 0, buffer.Length);
                    if (read <= 0)
                    {
                        return;
                    }
                    output.Write(buffer, 0, read);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        #endregion
    }

    public class TwitterObject
    {
        public string ID { get; set; }
        public string Title { get; set; }
        public DateTime Date { get; set; }
        public string AuthorName { get; set; }
        public string AuthorUri { get; set; }
        public string AuthorImage { get; set; }
    }
}